package com.juyu.miliao.api.service;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.juyu.miliao.api.dao.mysql.EnergyLevelDao;
import com.juyu.miliao.api.dao.mysql.UserInfoDao;
import com.juyu.miliao.api.util.HostUserLevelUtil;
import com.juyu.miliao.common.util.DoubleFormatUtil;
import com.juyu.miliao.common.util.SumAgeUtil;
import org.springframework.stereotype.Service;

import com.juyu.miliao.api.cache.GradeCache;
import com.juyu.miliao.api.dao.mysql.FollowDao;
import com.juyu.miliao.api.dao.mysql.UserCountDao;
import com.juyu.miliao.api.dao.redis.FollowRedisDao;
import com.juyu.miliao.api.dao.redis.LineTimeRedisDao;
import com.juyu.miliao.api.dao.redis.UserCallRedisDao;
import com.juyu.miliao.api.domain.Follow;
import com.juyu.miliao.api.domain.Grade;
import com.juyu.miliao.api.domain.User;
import com.juyu.miliao.api.util.GradeUtil;
import com.juyu.miliao.api.util.PageUtil;

import org.springframework.transaction.annotation.Transactional;

@Service
public class FollowService {
	@Resource
	private FollowDao followDao;
	@Resource
	private FollowRedisDao followRedisDao;
	@Resource
	private UserCountDao userCountDao;
	@Resource
	private LineTimeRedisDao lineTimeRedisDao;
	@Resource
	private UserCallRedisDao userCallRedisDao;
	@Resource
    private UserInfoDao userInfoDao;
	@Resource
	private EnergyLevelService energyLevelService;
	@Resource
	private IntegralLevelInfoService integralLevelInfoService;

	public List<User> getFollowById(long id,int page ,int pageSize) {
		int startNum = PageUtil.getOffset(page, pageSize);
		List<User> userList = new ArrayList<User>();
		
		Map<Integer,String> map= followRedisDao.getFollowIdsById(id, startNum, pageSize);
		if(map.size()==0)
			return userList;
		Set<Long> followIds = new HashSet<>();
		map.forEach((key,vale)->{
			followIds.add(key.longValue());
		});
		userList = followDao.getFollowById(followIds);
		// 魅力等级
//		List<Grade> mgradeList = GradeCache.INSTANCE.getGradeList(1);
//		List<Grade> vgradeList = GradeCache.INSTANCE.getGradeList(2);
		for(User user : userList){
//			user.setmGrade(GradeUtil.getGradeCount(mgradeList, user.getmGradeSum()));
//			 土豪等级
//			user.setvGrade(GradeUtil.getGradeCount(vgradeList, user.getvGradeSum()));
			user.setFollowDate(map.get(Integer.parseInt(user.getUserId()+"")));
			// 判断用户是否在线
			if (lineTimeRedisDao.hasKeyLine(user.getUserId() + ""))
				user.setIsLine(1);
			//如果用户为主播且正在通话中，则为繁忙状态 2018-08-28
			if(user.getIsHost() ==1 && userCallRedisDao.findHostCall(user.getUserId()+""))
				user.setIsLine(2);
			// 判断用户是否勿扰
			if (user.getIsVideo() == 2)
				user.setIsLine(3);
			// 生日转换成年龄
			if (user.getBirthday() != null) {
				user.setAge(SumAgeUtil.getAgeByBirth(user.getBirthday()));
			}
			//获取接通率
			double callSum = user.getCallSuccessSum() + user.getCallFailSum();
			if (callSum != 0) {
				double rate = (Double.parseDouble(user.getCallSuccessSum() + "") / callSum);
				user.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
			} else {
				user.setCallRate("100%");
			}
			if(user.getIsHost()==1){
				user.setHostUserLevelVo(HostUserLevelUtil
						.getHostUserLevel(integralLevelInfoService.getUserIntegralLevel(user.getIntegralSum())));
			}else{
				user.setEnergyLevel(energyLevelService.getUserEnergyLevel(user.getEnergySum()));
			}

		}
		return userList;
	}
	public List<User> getFansById(long id,int page ,int pageSize) {
		int startNum = PageUtil.getOffset(page, pageSize);
		List<Follow> fansList = followRedisDao.getFansById(id, startNum, pageSize);
		List<User> userList = new ArrayList<User>();
		if(fansList.size()==0)
			return userList;
		Map<Long, Follow> fansUserIdMap = fansList.stream()
				.collect(Collectors.toMap(Follow::getUserId, Function.identity()));
		userList = followDao.getFollowById(fansUserIdMap.keySet());
		// 魅力等级0
		List<Grade> mgradeList = GradeCache.INSTANCE.getGradeList(1);
		List<Grade> vgradeList = GradeCache.INSTANCE.getGradeList(2);
		userList.forEach(user->{
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
			user.setFollowDate(fansUserIdMap.get(user.getUserId()).getCreateTime().format(formatter));
			user.setmGrade(GradeUtil.getGradeCount(mgradeList, user.getmGradeSum()));
			// 土豪等级
			user.setvGrade(GradeUtil.getGradeCount(vgradeList, user.getvGradeSum()));
			// 判断用户是否在线
			if (lineTimeRedisDao.hasKeyLine(user.getUserId() + ""))
				user.setIsLine(1);
			//如果用户为主播且正在通话中，则为繁忙状态 2018-08-28
			if(user.getIsHost() == 1 && userCallRedisDao.findHostCall(user.getUserId()+""))
				user.setIsLine(2);
			// 判断用户是否勿扰
			if (user.getIsVideo() == 2)
				user.setIsLine(3);
			// 生日转换成年龄
			if (user.getBirthday() != null) {
				user.setAge(SumAgeUtil.getAgeByBirth(user.getBirthday()));
			}
			//获取接通率
			double callSum = user.getCallSuccessSum() + user.getCallFailSum();
			if (callSum != 0) {
				double rate = (Double.parseDouble(user.getCallSuccessSum() + "") / callSum);
				user.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
			} else {
				user.setCallRate("100%");
			}
		});
		return userList;
	}

	@Transactional(rollbackFor = Exception.class)
	public void insertFollow(Follow entity) {
		Boolean insertFollow = followRedisDao.insertFollow(entity);
		if(insertFollow){
			userCountDao.addFollowSum(entity.getUserId());
			userCountDao.addFansSum(entity.getFollowUserId());
		}

	}

	@Transactional(rollbackFor = Exception.class)
	public void deleteFollow(Follow entity) {
		long temp = followRedisDao.deleteFollow(entity);
		if(temp == 1){
		userCountDao.reduceFollowSum(entity.getUserId());
		userCountDao.reduceFansSum(entity.getFollowUserId());
		}
	}
	
	public String getFollowRelation(long userId, long tokenUserId) {
		String temp = "false";
		Optional<Long> countFollow = followRedisDao.countFollow(tokenUserId, userId);
		if (countFollow.isPresent())
			temp = "true";
		return temp;
	}

	public String getFollowRelationPassive(long userId, long tokenUserId) {
		String temp = "false";
		Optional<Long> countFollow = followRedisDao.countFollow(userId,tokenUserId);
		if (countFollow.isPresent())
			temp = "true";
		return temp;
	}

	public List<User> getFollowListById(Long userId){
		List<User> userList = new ArrayList<User>();
		Set<Long> followIds = followRedisDao.getFolllowAllByUserId(userId);
		if(followIds.size()==0){
			return userList;
		}
		//如果关注大于100 只查询100个人(问题：去掉的人可能在线，好处：查询快)
//		if(followIds.size()>100){
//			List<Long>list = new ArrayList<>(followIds);
//			followIds = new HashSet<>(list.subList(0,100));
//		}

		userList = followDao.getFollowById(followIds);
		// 魅力等级
		List<Grade> mgradeList = GradeCache.INSTANCE.getGradeList(1);
		List<Grade> vgradeList = GradeCache.INSTANCE.getGradeList(2);
		//存放有状态用户
		List<User> lineList = new ArrayList<User>();
		//无状态用户
		List<User> offLineList = new ArrayList<User>();
		for(User user : userList){
			user.setmGrade(GradeUtil.getGradeCount(mgradeList, user.getmGradeSum()));
			// 土豪等级
			user.setvGrade(GradeUtil.getGradeCount(vgradeList, user.getvGradeSum()));
			// 判断用户是否在线
			if (lineTimeRedisDao.hasKeyLine(user.getUserId() + ""))
				user.setIsLine(1);
			//如果用户为主播且正在通话中，则为繁忙状态 2018-08-28
			if(user.getIsHost() ==1 && userCallRedisDao.findHostCall(user.getUserId()+""))
				user.setIsLine(2);
			// 判断用户是否勿扰
			if (user.getIsVideo() == 2)
				user.setIsLine(3);
			// 生日转换成年龄
			if (user.getBirthday() != null) {
				user.setAge(SumAgeUtil.getAgeByBirth(user.getBirthday()));
			}
			//获取接通率
			double callSum = user.getCallSuccessSum() + user.getCallFailSum();
			if (callSum != 0) {
				double rate = (Double.parseDouble(user.getCallSuccessSum() + "") / callSum);
				user.setCallRate(DoubleFormatUtil.intFormate(DoubleFormatUtil.doubleFormate(rate) * 100) + "%");
			} else {
				user.setCallRate("100%");
			}
			if (user.getIsLine()!=0){
				lineList.add(user);
			}else{
				offLineList.add(user);
			}
		}
		//有状态用户排序
		lineList = lineList.stream().sorted(Comparator.comparing(User::getIsLine)).collect(Collectors.toList());
		//合并根据状态区分存贮的list
		lineList.addAll(offLineList);
		//如果关注大于100 只查询100个人(问题：查询慢)
		if (lineList.size()>100){
			lineList = new ArrayList<>(lineList.subList(0,100));
		}
		return lineList;
	}
}
